1   /*
2    * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   */
23  
24  /*
25   * @test
26   * @bug 4860891 4826732 4780454 4939441 4826652
27   * @summary Tests for IEEE 754[R] recommended functions and similar methods
28   * @author Joseph D. Darcy
29   */
30  
31  import sun.misc.FpUtils;
32  import sun.misc.DoubleConsts;
33  import sun.misc.FloatConsts;
34  
35  public class IeeeRecommendedTests {
36      private IeeeRecommendedTests(){}
37  
38      static final float  NaNf = Float.NaN;
39      static final double NaNd = Double.NaN;
40      static final float  infinityF = Float.POSITIVE_INFINITY;
41      static final double infinityD = Double.POSITIVE_INFINITY;
42  
43      static final float  Float_MAX_VALUEmm       = 0x1.fffffcP+127f;
44      static final float  Float_MAX_SUBNORMAL     = 0x0.fffffeP-126f;
45      static final float  Float_MAX_SUBNORMALmm   = 0x0.fffffcP-126f;
46  
47      static final double Double_MAX_VALUEmm      = 0x1.ffffffffffffeP+1023;
48      static final double Double_MAX_SUBNORMAL    = 0x0.fffffffffffffP-1022;
49      static final double Double_MAX_SUBNORMALmm  = 0x0.ffffffffffffeP-1022;
50  
51      // Initialize shared random number generator
52      static java.util.Random rand = new java.util.Random();
53  
54      /**
55       * Returns a floating-point power of two in the normal range.
56       */
57      static double powerOfTwoD(int n) {
58          return Double.longBitsToDouble((((long)n + (long)DoubleConsts.MAX_EXPONENT) <<
59                                          (DoubleConsts.SIGNIFICAND_WIDTH-1))
60                                         & DoubleConsts.EXP_BIT_MASK);
61      }
62  
63      /**
64       * Returns a floating-point power of two in the normal range.
65       */
66      static float powerOfTwoF(int n) {
67          return Float.intBitsToFloat(((n + FloatConsts.MAX_EXPONENT) <<
68                                       (FloatConsts.SIGNIFICAND_WIDTH-1))
69                                      & FloatConsts.EXP_BIT_MASK);
70      }
71  
72      /* ******************** getExponent tests ****************************** */
73  
74      /*
75       * The tests for getExponent should test the special values (NaN, +/-
76       * infinity, etc.), test the endpoints of each binade (set of
77       * floating-point values with the same exponent), and for good
78       * measure, test some random values within each binade.  Testing
79       * the endpoints of each binade includes testing both positive and
80       * negative numbers.  Subnormal values with different normalized
81       * exponents should be tested too.  Both Math and StrictMath
82       * methods should return the same results.
83       */
84  
85      /*
86       * Test Math.getExponent and StrictMath.getExponent with +d and -d.
87       */
88      static int testGetExponentCase(float f, int expected) {
89          float minus_f = -f;
90          int failures=0;
91  
92          failures+=Tests.test("Math.getExponent(float)", f,
93                               Math.getExponent(f), expected);
94          failures+=Tests.test("Math.getExponent(float)", minus_f,
95                               Math.getExponent(minus_f), expected);
96  
97          failures+=Tests.test("StrictMath.getExponent(float)", f,
98                               StrictMath.getExponent(f), expected);
99          failures+=Tests.test("StrictMath.getExponent(float)", minus_f,
100                              StrictMath.getExponent(minus_f), expected);
101         return failures;
102     }
103 
104     /*
105      * Test Math.getExponent and StrictMath.getExponent with +d and -d.
106      */
107     static int testGetExponentCase(double d, int expected) {
108         double minus_d = -d;
109         int failures=0;
110 
111         failures+=Tests.test("Math.getExponent(double)", d,
112                              Math.getExponent(d), expected);
113         failures+=Tests.test("Math.getExponent(double)", minus_d,
114                              Math.getExponent(minus_d), expected);
115 
116         failures+=Tests.test("StrictMath.getExponent(double)", d,
117                              StrictMath.getExponent(d), expected);
118         failures+=Tests.test("StrictMath.getExponent(double)", minus_d,
119                              StrictMath.getExponent(minus_d), expected);
120         return failures;
121     }
122 
123     public static int testFloatGetExponent() {
124         int failures = 0;
125         float [] specialValues = {NaNf,
126                                    Float.POSITIVE_INFINITY,
127                                    +0.0f,
128                                   +1.0f,
129                                   +2.0f,
130                                   +16.0f,
131                                   +Float.MIN_VALUE,
132                                   +Float_MAX_SUBNORMAL,
133                                   +FloatConsts.MIN_NORMAL,
134                                   +Float.MAX_VALUE
135         };
136 
137         int [] specialResults = {Float.MAX_EXPONENT + 1, // NaN results
138                                  Float.MAX_EXPONENT + 1, // Infinite results
139                                  Float.MIN_EXPONENT - 1, // Zero results
140                                  0,
141                                  1,
142                                  4,
143                                  FloatConsts.MIN_EXPONENT - 1,
144                                  -FloatConsts.MAX_EXPONENT,
145                                  FloatConsts.MIN_EXPONENT,
146                                  FloatConsts.MAX_EXPONENT
147         };
148 
149         // Special value tests
150         for(int i = 0; i < specialValues.length; i++) {
151             failures += testGetExponentCase(specialValues[i], specialResults[i]);
152         }
153 
154 
155         // Normal exponent tests
156         for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {
157             int result;
158 
159             // Create power of two
160             float po2 = powerOfTwoF(i);
161 
162             failures += testGetExponentCase(po2, i);
163 
164             // Generate some random bit patterns for the significand
165             for(int j = 0; j < 10; j++) {
166                 int randSignif = rand.nextInt();
167                 float randFloat;
168 
169                 randFloat = Float.intBitsToFloat( // Exponent
170                                                  (Float.floatToIntBits(po2)&
171                                                   (~FloatConsts.SIGNIF_BIT_MASK)) |
172                                                  // Significand
173                                                  (randSignif &
174                                                   FloatConsts.SIGNIF_BIT_MASK) );
175 
176                 failures += testGetExponentCase(randFloat, i);
177             }
178 
179             if (i > FloatConsts.MIN_EXPONENT) {
180                 float po2minus = FpUtils.nextAfter(po2,
181                                                  Float.NEGATIVE_INFINITY);
182                 failures += testGetExponentCase(po2minus, i-1);
183             }
184         }
185 
186         // Subnormal exponent tests
187 
188         /*
189          * Start with MIN_VALUE, left shift, test high value, low
190          * values, and random in between.
191          *
192          * Use nextAfter to calculate, high value of previous binade,
193          * loop count i will indicate how many random bits, if any are
194          * needed.
195          */
196 
197         float top=Float.MIN_VALUE;
198         for( int i = 1;
199             i < FloatConsts.SIGNIFICAND_WIDTH;
200             i++, top *= 2.0f) {
201 
202             failures += testGetExponentCase(top,
203                                             FloatConsts.MIN_EXPONENT - 1);
204 
205             // Test largest value in next smaller binade
206             if (i >= 3) {// (i == 1) would test 0.0;
207                          // (i == 2) would just retest MIN_VALUE
208                 testGetExponentCase(FpUtils.nextAfter(top, 0.0f),
209                                     FloatConsts.MIN_EXPONENT - 1);
210 
211                 if( i >= 10) {
212                     // create a bit mask with (i-1) 1's in the low order
213                     // bits
214                     int mask = ~((~0)<<(i-1));
215                     float randFloat = Float.intBitsToFloat( // Exponent
216                                                  Float.floatToIntBits(top) |
217                                                  // Significand
218                                                  (rand.nextInt() & mask ) ) ;
219 
220                     failures += testGetExponentCase(randFloat,
221                                                     FloatConsts.MIN_EXPONENT - 1);
222                 }
223             }
224         }
225 
226         return failures;
227     }
228 
229 
230     public static int testDoubleGetExponent() {
231         int failures = 0;
232         double [] specialValues = {NaNd,
233                                    infinityD,
234                                    +0.0,
235                                    +1.0,
236                                    +2.0,
237                                    +16.0,
238                                    +Double.MIN_VALUE,
239                                    +Double_MAX_SUBNORMAL,
240                                    +DoubleConsts.MIN_NORMAL,
241                                    +Double.MAX_VALUE
242         };
243 
244         int [] specialResults = {Double.MAX_EXPONENT + 1, // NaN results
245                                  Double.MAX_EXPONENT + 1, // Infinite results
246                                  Double.MIN_EXPONENT - 1, // Zero results
247                                  0,
248                                  1,
249                                  4,
250                                  DoubleConsts.MIN_EXPONENT - 1,
251                                  -DoubleConsts.MAX_EXPONENT,
252                                  DoubleConsts.MIN_EXPONENT,
253                                  DoubleConsts.MAX_EXPONENT
254         };
255 
256         // Special value tests
257         for(int i = 0; i < specialValues.length; i++) {
258             failures += testGetExponentCase(specialValues[i], specialResults[i]);
259         }
260 
261 
262         // Normal exponent tests
263         for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {
264             int result;
265 
266             // Create power of two
267             double po2 = powerOfTwoD(i);
268 
269             failures += testGetExponentCase(po2, i);
270 
271             // Generate some random bit patterns for the significand
272             for(int j = 0; j < 10; j++) {
273                 long randSignif = rand.nextLong();
274                 double randFloat;
275 
276                 randFloat = Double.longBitsToDouble( // Exponent
277                                                  (Double.doubleToLongBits(po2)&
278                                                   (~DoubleConsts.SIGNIF_BIT_MASK)) |
279                                                  // Significand
280                                                  (randSignif &
281                                                   DoubleConsts.SIGNIF_BIT_MASK) );
282 
283                 failures += testGetExponentCase(randFloat, i);
284             }
285 
286             if (i > DoubleConsts.MIN_EXPONENT) {
287                 double po2minus = FpUtils.nextAfter(po2,
288                                                     Double.NEGATIVE_INFINITY);
289                 failures += testGetExponentCase(po2minus, i-1);
290             }
291         }
292 
293         // Subnormal exponent tests
294 
295         /*
296          * Start with MIN_VALUE, left shift, test high value, low
297          * values, and random in between.
298          *
299          * Use nextAfter to calculate, high value of previous binade;
300          * loop count i will indicate how many random bits, if any are
301          * needed.
302          */
303 
304         double top=Double.MIN_VALUE;
305         for( int i = 1;
306             i < DoubleConsts.SIGNIFICAND_WIDTH;
307             i++, top *= 2.0f) {
308 
309             failures += testGetExponentCase(top,
310                                             DoubleConsts.MIN_EXPONENT - 1);
311 
312             // Test largest value in next smaller binade
313             if (i >= 3) {// (i == 1) would test 0.0;
314                          // (i == 2) would just retest MIN_VALUE
315                 testGetExponentCase(FpUtils.nextAfter(top, 0.0),
316                                     DoubleConsts.MIN_EXPONENT - 1);
317 
318                 if( i >= 10) {
319                     // create a bit mask with (i-1) 1's in the low order
320                     // bits
321                     long mask = ~((~0L)<<(i-1));
322                     double randFloat = Double.longBitsToDouble( // Exponent
323                                                  Double.doubleToLongBits(top) |
324                                                  // Significand
325                                                  (rand.nextLong() & mask ) ) ;
326 
327                     failures += testGetExponentCase(randFloat,
328                                                     DoubleConsts.MIN_EXPONENT - 1);
329                 }
330             }
331         }
332 
333         return failures;
334     }
335 
336 
337     /* ******************** nextAfter tests ****************************** */
338 
339     static int testNextAfterCase(float start, double direction, float expected) {
340         int failures=0;
341         float minus_start = -start;
342         double minus_direction = -direction;
343         float minus_expected = -expected;
344 
345         failures+=Tests.test("Math.nextAfter(float,double)", start, direction,
346                              Math.nextAfter(start, direction), expected);
347         failures+=Tests.test("Math.nextAfter(float,double)", minus_start, minus_direction,
348                              Math.nextAfter(minus_start, minus_direction), minus_expected);
349 
350         failures+=Tests.test("StrictMath.nextAfter(float,double)", start, direction,
351                              StrictMath.nextAfter(start, direction), expected);
352         failures+=Tests.test("StrictMath.nextAfter(float,double)", minus_start, minus_direction,
353                              StrictMath.nextAfter(minus_start, minus_direction), minus_expected);
354         return failures;
355     }
356 
357     static int testNextAfterCase(double start, double direction, double expected) {
358         int failures=0;
359 
360         double minus_start = -start;
361         double minus_direction = -direction;
362         double minus_expected = -expected;
363 
364         failures+=Tests.test("Math.nextAfter(double,double)", start, direction,
365                              Math.nextAfter(start, direction), expected);
366         failures+=Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction,
367                              Math.nextAfter(minus_start, minus_direction), minus_expected);
368 
369         failures+=Tests.test("StrictMath.nextAfter(double,double)", start, direction,
370                              StrictMath.nextAfter(start, direction), expected);
371         failures+=Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction,
372                              StrictMath.nextAfter(minus_start, minus_direction), minus_expected);
373         return failures;
374     }
375 
376     public static int testFloatNextAfter() {
377         int failures=0;
378 
379         /*
380          * Each row of the testCases matrix represents one test case
381          * for nexAfter; given the input of the first two columns, the
382          * result in the last column is expected.
383          */
384         float [][] testCases  = {
385             {NaNf,              NaNf,                   NaNf},
386             {NaNf,              0.0f,                   NaNf},
387             {0.0f,              NaNf,                   NaNf},
388             {NaNf,              infinityF,              NaNf},
389             {infinityF,         NaNf,                   NaNf},
390 
391             {infinityF,         infinityF,              infinityF},
392             {infinityF,         -infinityF,             Float.MAX_VALUE},
393             {infinityF,         0.0f,                   Float.MAX_VALUE},
394 
395             {Float.MAX_VALUE,   infinityF,              infinityF},
396             {Float.MAX_VALUE,   -infinityF,             Float_MAX_VALUEmm},
397             {Float.MAX_VALUE,   Float.MAX_VALUE,        Float.MAX_VALUE},
398             {Float.MAX_VALUE,   0.0f,                   Float_MAX_VALUEmm},
399 
400             {Float_MAX_VALUEmm, Float.MAX_VALUE,        Float.MAX_VALUE},
401             {Float_MAX_VALUEmm, infinityF,              Float.MAX_VALUE},
402             {Float_MAX_VALUEmm, Float_MAX_VALUEmm,      Float_MAX_VALUEmm},
403 
404             {FloatConsts.MIN_NORMAL,    infinityF,              FloatConsts.MIN_NORMAL+
405                                                                 Float.MIN_VALUE},
406             {FloatConsts.MIN_NORMAL,    -infinityF,             Float_MAX_SUBNORMAL},
407             {FloatConsts.MIN_NORMAL,    1.0f,                   FloatConsts.MIN_NORMAL+
408                                                                 Float.MIN_VALUE},
409             {FloatConsts.MIN_NORMAL,    -1.0f,                  Float_MAX_SUBNORMAL},
410             {FloatConsts.MIN_NORMAL,    FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},
411 
412             {Float_MAX_SUBNORMAL,       FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL},
413             {Float_MAX_SUBNORMAL,       Float_MAX_SUBNORMAL,    Float_MAX_SUBNORMAL},
414             {Float_MAX_SUBNORMAL,       0.0f,                   Float_MAX_SUBNORMALmm},
415 
416             {Float_MAX_SUBNORMALmm,     Float_MAX_SUBNORMAL,    Float_MAX_SUBNORMAL},
417             {Float_MAX_SUBNORMALmm,     0.0f,                   Float_MAX_SUBNORMALmm-Float.MIN_VALUE},
418             {Float_MAX_SUBNORMALmm,     Float_MAX_SUBNORMALmm,  Float_MAX_SUBNORMALmm},
419 
420             {Float.MIN_VALUE,   0.0f,                   0.0f},
421             {-Float.MIN_VALUE,  0.0f,                   -0.0f},
422             {Float.MIN_VALUE,   Float.MIN_VALUE,        Float.MIN_VALUE},
423             {Float.MIN_VALUE,   1.0f,                   2*Float.MIN_VALUE},
424 
425             // Make sure zero behavior is tested
426             {0.0f,              0.0f,                   0.0f},
427             {0.0f,              -0.0f,                  -0.0f},
428             {-0.0f,             0.0f,                   0.0f},
429             {-0.0f,             -0.0f,                  -0.0f},
430             {0.0f,              infinityF,              Float.MIN_VALUE},
431             {0.0f,              -infinityF,             -Float.MIN_VALUE},
432             {-0.0f,             infinityF,              Float.MIN_VALUE},
433             {-0.0f,             -infinityF,             -Float.MIN_VALUE},
434             {0.0f,              Float.MIN_VALUE,        Float.MIN_VALUE},
435             {0.0f,              -Float.MIN_VALUE,       -Float.MIN_VALUE},
436             {-0.0f,             Float.MIN_VALUE,        Float.MIN_VALUE},
437             {-0.0f,             -Float.MIN_VALUE,       -Float.MIN_VALUE}
438         };
439 
440         for(int i = 0; i < testCases.length; i++) {
441             failures += testNextAfterCase(testCases[i][0], testCases[i][1],
442                                           testCases[i][2]);
443         }
444 
445         return failures;
446     }
447 
448     public static int testDoubleNextAfter() {
449         int failures =0;
450 
451         /*
452          * Each row of the testCases matrix represents one test case
453          * for nexAfter; given the input of the first two columns, the
454          * result in the last column is expected.
455          */
456         double [][] testCases  = {
457             {NaNd,              NaNd,                   NaNd},
458             {NaNd,              0.0d,                   NaNd},
459             {0.0d,              NaNd,                   NaNd},
460             {NaNd,              infinityD,              NaNd},
461             {infinityD,         NaNd,                   NaNd},
462 
463             {infinityD,         infinityD,              infinityD},
464             {infinityD,         -infinityD,             Double.MAX_VALUE},
465             {infinityD,         0.0d,                   Double.MAX_VALUE},
466 
467             {Double.MAX_VALUE,  infinityD,              infinityD},
468             {Double.MAX_VALUE,  -infinityD,             Double_MAX_VALUEmm},
469             {Double.MAX_VALUE,  Double.MAX_VALUE,       Double.MAX_VALUE},
470             {Double.MAX_VALUE,  0.0d,                   Double_MAX_VALUEmm},
471 
472             {Double_MAX_VALUEmm,        Double.MAX_VALUE,       Double.MAX_VALUE},
473             {Double_MAX_VALUEmm,        infinityD,              Double.MAX_VALUE},
474             {Double_MAX_VALUEmm,        Double_MAX_VALUEmm,     Double_MAX_VALUEmm},
475 
476             {DoubleConsts.MIN_NORMAL,   infinityD,              DoubleConsts.MIN_NORMAL+
477                                                                 Double.MIN_VALUE},
478             {DoubleConsts.MIN_NORMAL,   -infinityD,             Double_MAX_SUBNORMAL},
479             {DoubleConsts.MIN_NORMAL,   1.0f,                   DoubleConsts.MIN_NORMAL+
480                                                                 Double.MIN_VALUE},
481             {DoubleConsts.MIN_NORMAL,   -1.0f,                  Double_MAX_SUBNORMAL},
482             {DoubleConsts.MIN_NORMAL,   DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},
483 
484             {Double_MAX_SUBNORMAL,      DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL},
485             {Double_MAX_SUBNORMAL,      Double_MAX_SUBNORMAL,   Double_MAX_SUBNORMAL},
486             {Double_MAX_SUBNORMAL,      0.0d,                   Double_MAX_SUBNORMALmm},
487 
488             {Double_MAX_SUBNORMALmm,    Double_MAX_SUBNORMAL,   Double_MAX_SUBNORMAL},
489             {Double_MAX_SUBNORMALmm,    0.0d,                   Double_MAX_SUBNORMALmm-Double.MIN_VALUE},
490             {Double_MAX_SUBNORMALmm,    Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm},
491 
492             {Double.MIN_VALUE,  0.0d,                   0.0d},
493             {-Double.MIN_VALUE, 0.0d,                   -0.0d},
494             {Double.MIN_VALUE,  Double.MIN_VALUE,       Double.MIN_VALUE},
495             {Double.MIN_VALUE,  1.0f,                   2*Double.MIN_VALUE},
496 
497             // Make sure zero behavior is tested
498             {0.0d,              0.0d,                   0.0d},
499             {0.0d,              -0.0d,                  -0.0d},
500             {-0.0d,             0.0d,                   0.0d},
501             {-0.0d,             -0.0d,                  -0.0d},
502             {0.0d,              infinityD,              Double.MIN_VALUE},
503             {0.0d,              -infinityD,             -Double.MIN_VALUE},
504             {-0.0d,             infinityD,              Double.MIN_VALUE},
505             {-0.0d,             -infinityD,             -Double.MIN_VALUE},
506             {0.0d,              Double.MIN_VALUE,       Double.MIN_VALUE},
507             {0.0d,              -Double.MIN_VALUE,      -Double.MIN_VALUE},
508             {-0.0d,             Double.MIN_VALUE,       Double.MIN_VALUE},
509             {-0.0d,             -Double.MIN_VALUE,      -Double.MIN_VALUE}
510         };
511 
512         for(int i = 0; i < testCases.length; i++) {
513             failures += testNextAfterCase(testCases[i][0], testCases[i][1],
514                                           testCases[i][2]);
515         }
516         return failures;
517     }
518 
519     /* ******************** nextUp tests ********************************* */
520 
521     public static int testFloatNextUp() {
522         int failures=0;
523 
524         /*
525          * Each row of testCases represents one test case for nextUp;
526          * the first column is the input and the second column is the
527          * expected result.
528          */
529         float testCases [][] = {
530             {NaNf,                      NaNf},
531             {-infinityF,                -Float.MAX_VALUE},
532             {-Float.MAX_VALUE,          -Float_MAX_VALUEmm},
533             {-FloatConsts.MIN_NORMAL,   -Float_MAX_SUBNORMAL},
534             {-Float_MAX_SUBNORMAL,      -Float_MAX_SUBNORMALmm},
535             {-Float.MIN_VALUE,          -0.0f},
536             {-0.0f,                     Float.MIN_VALUE},
537             {+0.0f,                     Float.MIN_VALUE},
538             {Float.MIN_VALUE,           Float.MIN_VALUE*2},
539             {Float_MAX_SUBNORMALmm,     Float_MAX_SUBNORMAL},
540             {Float_MAX_SUBNORMAL,       FloatConsts.MIN_NORMAL},
541             {FloatConsts.MIN_NORMAL,    FloatConsts.MIN_NORMAL+Float.MIN_VALUE},
542             {Float_MAX_VALUEmm,         Float.MAX_VALUE},
543             {Float.MAX_VALUE,           infinityF},
544             {infinityF,                 infinityF}
545         };
546 
547         for(int i = 0; i < testCases.length; i++) {
548             failures+=Tests.test("Math.nextUp(float)",
549                                  testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);
550 
551             failures+=Tests.test("StrictMath.nextUp(float)",
552                                  testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);
553         }
554 
555         return failures;
556     }
557 
558 
559     public static int testDoubleNextUp() {
560         int failures=0;
561 
562         /*
563          * Each row of testCases represents one test case for nextUp;
564          * the first column is the input and the second column is the
565          * expected result.
566          */
567         double testCases [][] = {
568             {NaNd,                      NaNd},
569             {-infinityD,                -Double.MAX_VALUE},
570             {-Double.MAX_VALUE,         -Double_MAX_VALUEmm},
571             {-DoubleConsts.MIN_NORMAL,  -Double_MAX_SUBNORMAL},
572             {-Double_MAX_SUBNORMAL,     -Double_MAX_SUBNORMALmm},
573             {-Double.MIN_VALUE,         -0.0d},
574             {-0.0d,                     Double.MIN_VALUE},
575             {+0.0d,                     Double.MIN_VALUE},
576             {Double.MIN_VALUE,          Double.MIN_VALUE*2},
577             {Double_MAX_SUBNORMALmm,    Double_MAX_SUBNORMAL},
578             {Double_MAX_SUBNORMAL,      DoubleConsts.MIN_NORMAL},
579             {DoubleConsts.MIN_NORMAL,   DoubleConsts.MIN_NORMAL+Double.MIN_VALUE},
580             {Double_MAX_VALUEmm,        Double.MAX_VALUE},
581             {Double.MAX_VALUE,          infinityD},
582             {infinityD,                 infinityD}
583         };
584 
585         for(int i = 0; i < testCases.length; i++) {
586             failures+=Tests.test("Math.nextUp(double)",
587                                  testCases[i][0], Math.nextUp(testCases[i][0]), testCases[i][1]);
588 
589             failures+=Tests.test("StrictMath.nextUp(double)",
590                                  testCases[i][0], StrictMath.nextUp(testCases[i][0]), testCases[i][1]);
591         }
592 
593         return failures;
594     }
595 
596     /* ******************** nextDown tests ********************************* */
597 
598     public static int testFloatNextDown() {
599         int failures=0;
600 
601         /*
602          * Each row of testCases represents one test case for nextDown;
603          * the first column is the input and the second column is the
604          * expected result.
605          */
606         float testCases [][] = {
607             {NaNf,                      NaNf},
608             {-infinityF,                -infinityF},
609             {-Float.MAX_VALUE,          -infinityF},
610             {-Float_MAX_VALUEmm,        -Float.MAX_VALUE},
611             {-Float_MAX_SUBNORMAL,      -FloatConsts.MIN_NORMAL},
612             {-Float_MAX_SUBNORMALmm,    -Float_MAX_SUBNORMAL},
613             {-0.0f,                     -Float.MIN_VALUE},
614             {+0.0f,                     -Float.MIN_VALUE},
615             {Float.MIN_VALUE,           0.0f},
616             {Float.MIN_VALUE*2,         Float.MIN_VALUE},
617             {Float_MAX_SUBNORMAL,       Float_MAX_SUBNORMALmm},
618             {FloatConsts.MIN_NORMAL,    Float_MAX_SUBNORMAL},
619             {FloatConsts.MIN_NORMAL+
620              Float.MIN_VALUE,           FloatConsts.MIN_NORMAL},
621             {Float.MAX_VALUE,           Float_MAX_VALUEmm},
622             {infinityF,                 Float.MAX_VALUE},
623         };
624 
625         for(int i = 0; i < testCases.length; i++) {
626             failures+=Tests.test("FpUtils.nextDown(float)",
627                                  testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]);
628         }
629 
630         return failures;
631     }
632 
633 
634     public static int testDoubleNextDown() {
635         int failures=0;
636 
637         /*
638          * Each row of testCases represents one test case for nextDown;
639          * the first column is the input and the second column is the
640          * expected result.
641          */
642         double testCases [][] = {
643             {NaNd,                      NaNd},
644             {-infinityD,                -infinityD},
645             {-Double.MAX_VALUE,         -infinityD},
646             {-Double_MAX_VALUEmm,       -Double.MAX_VALUE},
647             {-Double_MAX_SUBNORMAL,     -DoubleConsts.MIN_NORMAL},
648             {-Double_MAX_SUBNORMALmm,   -Double_MAX_SUBNORMAL},
649             {-0.0d,                     -Double.MIN_VALUE},
650             {+0.0d,                     -Double.MIN_VALUE},
651             {Double.MIN_VALUE,          0.0d},
652             {Double.MIN_VALUE*2,        Double.MIN_VALUE},
653             {Double_MAX_SUBNORMAL,      Double_MAX_SUBNORMALmm},
654             {DoubleConsts.MIN_NORMAL,   Double_MAX_SUBNORMAL},
655             {DoubleConsts.MIN_NORMAL+
656              Double.MIN_VALUE,          DoubleConsts.MIN_NORMAL},
657             {Double.MAX_VALUE,          Double_MAX_VALUEmm},
658             {infinityD,                 Double.MAX_VALUE},
659         };
660 
661         for(int i = 0; i < testCases.length; i++) {
662             failures+=Tests.test("FpUtils.nextDown(double)",
663                                  testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]);
664         }
665 
666         return failures;
667     }
668 
669 
670     /* ********************** boolean tests ****************************** */
671 
672     /*
673      * Combined tests for boolean functions, isFinite, isInfinite,
674      * isNaN, isUnordered.
675      */
676 
677     public static int testFloatBooleanMethods() {
678         int failures = 0;
679 
680         float testCases [] = {
681             NaNf,
682             -infinityF,
683             infinityF,
684             -Float.MAX_VALUE,
685             -3.0f,
686             -1.0f,
687             -FloatConsts.MIN_NORMAL,
688             -Float_MAX_SUBNORMALmm,
689             -Float_MAX_SUBNORMAL,
690             -Float.MIN_VALUE,
691             -0.0f,
692             +0.0f,
693             Float.MIN_VALUE,
694             Float_MAX_SUBNORMALmm,
695             Float_MAX_SUBNORMAL,
696             FloatConsts.MIN_NORMAL,
697             1.0f,
698             3.0f,
699             Float_MAX_VALUEmm,
700             Float.MAX_VALUE
701         };
702 
703         for(int i = 0; i < testCases.length; i++) {
704             // isNaN
705             failures+=Tests.test("FpUtils.isNaN(float)", testCases[i],
706                                  FpUtils.isNaN(testCases[i]), (i ==0));
707 
708             // isFinite
709             failures+=Tests.test("FpUtils.isFinite(float)", testCases[i],
710                                  FpUtils.isFinite(testCases[i]), (i >= 3));
711 
712             // isInfinite
713             failures+=Tests.test("FpUtils.isInfinite(float)", testCases[i],
714                                  FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
715 
716             // isUnorderd
717             for(int j = 0; j < testCases.length; j++) {
718                 failures+=Tests.test("FpUtils.isUnordered(float, float)", testCases[i],testCases[j],
719                                      FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
720             }
721         }
722 
723         return failures;
724     }
725 
726     public static int testDoubleBooleanMethods() {
727         int failures = 0;
728         boolean result = false;
729 
730         double testCases [] = {
731             NaNd,
732             -infinityD,
733             infinityD,
734             -Double.MAX_VALUE,
735             -3.0d,
736             -1.0d,
737             -DoubleConsts.MIN_NORMAL,
738             -Double_MAX_SUBNORMALmm,
739             -Double_MAX_SUBNORMAL,
740             -Double.MIN_VALUE,
741             -0.0d,
742             +0.0d,
743             Double.MIN_VALUE,
744             Double_MAX_SUBNORMALmm,
745             Double_MAX_SUBNORMAL,
746             DoubleConsts.MIN_NORMAL,
747             1.0d,
748             3.0d,
749             Double_MAX_VALUEmm,
750             Double.MAX_VALUE
751         };
752 
753         for(int i = 0; i < testCases.length; i++) {
754             // isNaN
755             failures+=Tests.test("FpUtils.isNaN(double)", testCases[i],
756                                  FpUtils.isNaN(testCases[i]), (i ==0));
757 
758             // isFinite
759             failures+=Tests.test("FpUtils.isFinite(double)", testCases[i],
760                                  FpUtils.isFinite(testCases[i]), (i >= 3));
761 
762             // isInfinite
763             failures+=Tests.test("FpUtils.isInfinite(double)", testCases[i],
764                                  FpUtils.isInfinite(testCases[i]), (i==1 || i==2));
765 
766             // isUnorderd
767             for(int j = 0; j < testCases.length; j++) {
768                 failures+=Tests.test("FpUtils.isUnordered(double, double)", testCases[i],testCases[j],
769                                      FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0));
770             }
771         }
772 
773         return failures;
774     }
775 
776     /* ******************** copySign tests******************************** */
777 
778    public static int testFloatCopySign() {
779         int failures = 0;
780 
781         // testCases[0] are logically positive numbers;
782         // testCases[1] are negative numbers.
783         float testCases [][] = {
784             {+0.0f,
785              Float.MIN_VALUE,
786              Float_MAX_SUBNORMALmm,
787              Float_MAX_SUBNORMAL,
788              FloatConsts.MIN_NORMAL,
789              1.0f,
790              3.0f,
791              Float_MAX_VALUEmm,
792              Float.MAX_VALUE,
793              infinityF,
794             },
795             {-infinityF,
796              -Float.MAX_VALUE,
797              -3.0f,
798              -1.0f,
799              -FloatConsts.MIN_NORMAL,
800              -Float_MAX_SUBNORMALmm,
801              -Float_MAX_SUBNORMAL,
802              -Float.MIN_VALUE,
803              -0.0f}
804         };
805 
806         float NaNs[] = {Float.intBitsToFloat(0x7fc00000),       // "positive" NaN
807                         Float.intBitsToFloat(0xFfc00000)};      // "negative" NaN
808 
809         // Tests shared between raw and non-raw versions
810         for(int i = 0; i < 2; i++) {
811             for(int j = 0; j < 2; j++) {
812                 for(int m = 0; m < testCases[i].length; m++) {
813                     for(int n = 0; n < testCases[j].length; n++) {
814                         // copySign(magnitude, sign)
815                         failures+=Tests.test("Math.copySign(float,float)",
816                                              testCases[i][m],testCases[j][n],
817                                              Math.copySign(testCases[i][m], testCases[j][n]),
818                                              (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
819 
820                         failures+=Tests.test("StrictMath.copySign(float,float)",
821                                              testCases[i][m],testCases[j][n],
822                                              StrictMath.copySign(testCases[i][m], testCases[j][n]),
823                                              (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
824                     }
825                 }
826             }
827         }
828 
829         // For rawCopySign, NaN may effectively have either sign bit
830         // while for copySign NaNs are treated as if they always have
831         // a zero sign bit (i.e. as positive numbers)
832         for(int i = 0; i < 2; i++) {
833             for(int j = 0; j < NaNs.length; j++) {
834                 for(int m = 0; m < testCases[i].length; m++) {
835                     // copySign(magnitude, sign)
836 
837                     failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==
838                                  Math.abs(testCases[i][m])) ? 0:1;
839 
840 
841                     failures+=Tests.test("StrictMath.copySign(float,float)",
842                                          testCases[i][m], NaNs[j],
843                                          StrictMath.copySign(testCases[i][m], NaNs[j]),
844                                          Math.abs(testCases[i][m]) );
845                 }
846             }
847         }
848 
849         return failures;
850     }
851 
852     public static int testDoubleCopySign() {
853         int failures = 0;
854 
855         // testCases[0] are logically positive numbers;
856         // testCases[1] are negative numbers.
857         double testCases [][] = {
858             {+0.0d,
859              Double.MIN_VALUE,
860              Double_MAX_SUBNORMALmm,
861              Double_MAX_SUBNORMAL,
862              DoubleConsts.MIN_NORMAL,
863              1.0d,
864              3.0d,
865              Double_MAX_VALUEmm,
866              Double.MAX_VALUE,
867              infinityD,
868             },
869             {-infinityD,
870              -Double.MAX_VALUE,
871              -3.0d,
872              -1.0d,
873              -DoubleConsts.MIN_NORMAL,
874              -Double_MAX_SUBNORMALmm,
875              -Double_MAX_SUBNORMAL,
876              -Double.MIN_VALUE,
877              -0.0d}
878         };
879 
880         double NaNs[] = {Double.longBitsToDouble(0x7ff8000000000000L),  // "positive" NaN
881                          Double.longBitsToDouble(0xfff8000000000000L),  // "negative" NaN
882                          Double.longBitsToDouble(0x7FF0000000000001L),
883                          Double.longBitsToDouble(0xFFF0000000000001L),
884                          Double.longBitsToDouble(0x7FF8555555555555L),
885                          Double.longBitsToDouble(0xFFF8555555555555L),
886                          Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL),
887                          Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL),
888                          Double.longBitsToDouble(0x7FFDeadBeef00000L),
889                          Double.longBitsToDouble(0xFFFDeadBeef00000L),
890                          Double.longBitsToDouble(0x7FFCafeBabe00000L),
891                          Double.longBitsToDouble(0xFFFCafeBabe00000L)};
892 
893         // Tests shared between Math and StrictMath versions
894         for(int i = 0; i < 2; i++) {
895             for(int j = 0; j < 2; j++) {
896                 for(int m = 0; m < testCases[i].length; m++) {
897                     for(int n = 0; n < testCases[j].length; n++) {
898                         // copySign(magnitude, sign)
899                         failures+=Tests.test("MathcopySign(double,double)",
900                                              testCases[i][m],testCases[j][n],
901                                              Math.copySign(testCases[i][m], testCases[j][n]),
902                                              (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
903 
904                         failures+=Tests.test("StrictMath.copySign(double,double)",
905                                              testCases[i][m],testCases[j][n],
906                                              StrictMath.copySign(testCases[i][m], testCases[j][n]),
907                                              (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) );
908                     }
909                 }
910             }
911         }
912 
913         // For Math.copySign, NaN may effectively have either sign bit
914         // while for StrictMath.copySign NaNs are treated as if they
915         // always have a zero sign bit (i.e. as positive numbers)
916         for(int i = 0; i < 2; i++) {
917             for(int j = 0; j < NaNs.length; j++) {
918                 for(int m = 0; m < testCases[i].length; m++) {
919                     // copySign(magnitude, sign)
920 
921                     failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) ==
922                                  Math.abs(testCases[i][m])) ? 0:1;
923 
924 
925                     failures+=Tests.test("StrictMath.copySign(double,double)",
926                                          testCases[i][m], NaNs[j],
927                                          StrictMath.copySign(testCases[i][m], NaNs[j]),
928                                          Math.abs(testCases[i][m]) );
929                 }
930             }
931         }
932 
933 
934         return failures;
935     }
936 
937     /* ************************ scalb tests ******************************* */
938 
939     static int testScalbCase(float value, int scale_factor, float expected) {
940         int failures=0;
941 
942         failures+=Tests.test("Math.scalb(float,int)",
943                              value, scale_factor,
944                              Math.scalb(value, scale_factor), expected);
945 
946         failures+=Tests.test("Math.scalb(float,int)",
947                              -value, scale_factor,
948                              Math.scalb(-value, scale_factor), -expected);
949 
950         failures+=Tests.test("StrictMath.scalb(float,int)",
951                              value, scale_factor,
952                              StrictMath.scalb(value, scale_factor), expected);
953 
954         failures+=Tests.test("StrictMath.scalb(float,int)",
955                              -value, scale_factor,
956                              StrictMath.scalb(-value, scale_factor), -expected);
957         return failures;
958     }
959 
960     public static int testFloatScalb() {
961         int failures=0;
962         int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT +
963                         FloatConsts.SIGNIFICAND_WIDTH + 1;
964 
965 
966         // Arguments x, where scalb(x,n) is x for any n.
967         float [] identityTestCases = {NaNf,
968                                       -0.0f,
969                                       +0.0f,
970                                       infinityF,
971                                       -infinityF
972         };
973 
974         float [] subnormalTestCases = {
975             Float.MIN_VALUE,
976             3.0f*Float.MIN_VALUE,
977             Float_MAX_SUBNORMALmm,
978             Float_MAX_SUBNORMAL
979         };
980 
981         float [] someTestCases = {
982             Float.MIN_VALUE,
983             3.0f*Float.MIN_VALUE,
984             Float_MAX_SUBNORMALmm,
985             Float_MAX_SUBNORMAL,
986             FloatConsts.MIN_NORMAL,
987             1.0f,
988             2.0f,
989             3.0f,
990             (float)Math.PI,
991             Float_MAX_VALUEmm,
992             Float.MAX_VALUE
993         };
994 
995         int [] oneMultiplyScalingFactors = {
996             FloatConsts.MIN_EXPONENT,
997             FloatConsts.MIN_EXPONENT+1,
998             -3,
999             -2,
1000             -1,
1001             0,
1002             1,
1003             2,
1004             3,
1005             FloatConsts.MAX_EXPONENT-1,
1006             FloatConsts.MAX_EXPONENT
1007         };
1008 
1009         int [] manyScalingFactors = {
1010             Integer.MIN_VALUE,
1011             Integer.MIN_VALUE+1,
1012             -MAX_SCALE -1,
1013             -MAX_SCALE,
1014             -MAX_SCALE+1,
1015 
1016             2*FloatConsts.MIN_EXPONENT-1,       // -253
1017             2*FloatConsts.MIN_EXPONENT,         // -252
1018             2*FloatConsts.MIN_EXPONENT+1,       // -251
1019 
1020             FpUtils.ilogb(Float.MIN_VALUE)-1,   // -150
1021             FpUtils.ilogb(Float.MIN_VALUE),     // -149
1022             -FloatConsts.MAX_EXPONENT,          // -127
1023             FloatConsts.MIN_EXPONENT,           // -126
1024 
1025             -2,
1026             -1,
1027             0,
1028             1,
1029             2,
1030 
1031             FloatConsts.MAX_EXPONENT-1,         // 126
1032             FloatConsts.MAX_EXPONENT,           // 127
1033             FloatConsts.MAX_EXPONENT+1,         // 128
1034 
1035             2*FloatConsts.MAX_EXPONENT-1,       // 253
1036             2*FloatConsts.MAX_EXPONENT,         // 254
1037             2*FloatConsts.MAX_EXPONENT+1,       // 255
1038 
1039             MAX_SCALE-1,
1040             MAX_SCALE,
1041             MAX_SCALE+1,
1042             Integer.MAX_VALUE-1,
1043             Integer.MAX_VALUE
1044         };
1045 
1046         // Test cases where scaling is always a no-op
1047         for(int i=0; i < identityTestCases.length; i++) {
1048             for(int j=0; j < manyScalingFactors.length; j++) {
1049                 failures += testScalbCase(identityTestCases[i],
1050                                           manyScalingFactors[j],
1051                                           identityTestCases[i]);
1052             }
1053         }
1054 
1055         // Test cases where result is 0.0 or infinity due to magnitude
1056         // of the scaling factor
1057         for(int i=0; i < someTestCases.length; i++) {
1058             for(int j=0; j < manyScalingFactors.length; j++) {
1059                 int scaleFactor = manyScalingFactors[j];
1060                 if (Math.abs(scaleFactor) >= MAX_SCALE) {
1061                     float value = someTestCases[i];
1062                     failures+=testScalbCase(value,
1063                                             scaleFactor,
1064                                             FpUtils.copySign( (scaleFactor>0?infinityF:0.0f), value) );
1065                 }
1066             }
1067         }
1068 
1069         // Test cases that could be done with one floating-point
1070         // multiply.
1071         for(int i=0; i < someTestCases.length; i++) {
1072             for(int j=0; j < oneMultiplyScalingFactors.length; j++) {
1073                 int scaleFactor = oneMultiplyScalingFactors[j];
1074                     float value = someTestCases[i];
1075 
1076                     failures+=testScalbCase(value,
1077                                             scaleFactor,
1078                                             value*powerOfTwoF(scaleFactor));
1079             }
1080         }
1081 
1082         // Create 2^MAX_EXPONENT
1083         float twoToTheMaxExp = 1.0f; // 2^0
1084         for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++)
1085             twoToTheMaxExp *=2.0f;
1086 
1087         // Scale-up subnormal values until they all overflow
1088         for(int i=0; i < subnormalTestCases.length; i++) {
1089             float scale = 1.0f; // 2^j
1090             float value = subnormalTestCases[i];
1091 
1092             for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1093                 int scaleFactor = j;
1094 
1095                 failures+=testScalbCase(value,
1096                                         scaleFactor,
1097                                         (FpUtils.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ?
1098                                         FpUtils.copySign(infinityF, value) : // overflow
1099                                         // calculate right answer
1100                                         twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1101                 scale*=2.0f;
1102             }
1103         }
1104 
1105         // Scale down a large number until it underflows.  By scaling
1106         // down MAX_NORMALmm, the first subnormal result will be exact
1107         // but the next one will round -- all those results can be
1108         // checked by halving a separate value in the loop.  Actually,
1109         // we can keep halving and checking until the product is zero
1110         // since:
1111         //
1112         // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1113         // it will round *up*
1114         //
1115         // 2. When rounding first occurs in the expected product, it
1116         // too rounds up, to 2^-MAX_EXPONENT.
1117         //
1118         // Halving expected after rounding happends to give the same
1119         // result as the scalb operation.
1120         float expected = Float_MAX_VALUEmm *0.5f;
1121         for(int i = -1; i > -MAX_SCALE; i--) {
1122             failures+=testScalbCase(Float_MAX_VALUEmm, i, expected);
1123 
1124             expected *= 0.5f;
1125         }
1126 
1127         // Tricky rounding tests:
1128         // Scale down a large number into subnormal range such that if
1129         // scalb is being implemented with multiple floating-point
1130         // multiplies, the value would round twice if the multiplies
1131         // were done in the wrong order.
1132 
1133         float value = 0x8.0000bP-5f;
1134         expected = 0x1.00001p-129f;
1135 
1136         for(int i = 0; i < 129; i++) {
1137             failures+=testScalbCase(value,
1138                                     -127-i,
1139                                     expected);
1140             value *=2.0f;
1141         }
1142 
1143         return failures;
1144     }
1145 
1146     static int testScalbCase(double value, int scale_factor, double expected) {
1147         int failures=0;
1148 
1149         failures+=Tests.test("Math.scalb(double,int)",
1150                              value, scale_factor,
1151                              Math.scalb(value, scale_factor), expected);
1152 
1153         failures+=Tests.test("Math.scalb(double,int)",
1154                              -value, scale_factor,
1155                              Math.scalb(-value, scale_factor), -expected);
1156 
1157         failures+=Tests.test("StrictMath.scalb(double,int)",
1158                              value, scale_factor,
1159                              StrictMath.scalb(value, scale_factor), expected);
1160 
1161         failures+=Tests.test("StrictMath.scalb(double,int)",
1162                              -value, scale_factor,
1163                              StrictMath.scalb(-value, scale_factor), -expected);
1164 
1165         return failures;
1166     }
1167 
1168     public static int testDoubleScalb() {
1169         int failures=0;
1170         int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT +
1171                         DoubleConsts.SIGNIFICAND_WIDTH + 1;
1172 
1173 
1174         // Arguments x, where scalb(x,n) is x for any n.
1175         double [] identityTestCases = {NaNd,
1176                                       -0.0,
1177                                       +0.0,
1178                                       infinityD,
1179         };
1180 
1181         double [] subnormalTestCases = {
1182             Double.MIN_VALUE,
1183             3.0d*Double.MIN_VALUE,
1184             Double_MAX_SUBNORMALmm,
1185             Double_MAX_SUBNORMAL
1186         };
1187 
1188         double [] someTestCases = {
1189             Double.MIN_VALUE,
1190             3.0d*Double.MIN_VALUE,
1191             Double_MAX_SUBNORMALmm,
1192             Double_MAX_SUBNORMAL,
1193             DoubleConsts.MIN_NORMAL,
1194             1.0d,
1195             2.0d,
1196             3.0d,
1197             Math.PI,
1198             Double_MAX_VALUEmm,
1199             Double.MAX_VALUE
1200         };
1201 
1202         int [] oneMultiplyScalingFactors = {
1203             DoubleConsts.MIN_EXPONENT,
1204             DoubleConsts.MIN_EXPONENT+1,
1205             -3,
1206             -2,
1207             -1,
1208             0,
1209             1,
1210             2,
1211             3,
1212             DoubleConsts.MAX_EXPONENT-1,
1213             DoubleConsts.MAX_EXPONENT
1214         };
1215 
1216         int [] manyScalingFactors = {
1217             Integer.MIN_VALUE,
1218             Integer.MIN_VALUE+1,
1219             -MAX_SCALE -1,
1220             -MAX_SCALE,
1221             -MAX_SCALE+1,
1222 
1223             2*DoubleConsts.MIN_EXPONENT-1,      // -2045
1224             2*DoubleConsts.MIN_EXPONENT,        // -2044
1225             2*DoubleConsts.MIN_EXPONENT+1,      // -2043
1226 
1227             FpUtils.ilogb(Double.MIN_VALUE)-1,  // -1076
1228             FpUtils.ilogb(Double.MIN_VALUE),    // -1075
1229             -DoubleConsts.MAX_EXPONENT,         // -1023
1230             DoubleConsts.MIN_EXPONENT,          // -1022
1231 
1232             -2,
1233             -1,
1234             0,
1235             1,
1236             2,
1237 
1238             DoubleConsts.MAX_EXPONENT-1,        // 1022
1239             DoubleConsts.MAX_EXPONENT,          // 1023
1240             DoubleConsts.MAX_EXPONENT+1,        // 1024
1241 
1242             2*DoubleConsts.MAX_EXPONENT-1,      // 2045
1243             2*DoubleConsts.MAX_EXPONENT,        // 2046
1244             2*DoubleConsts.MAX_EXPONENT+1,      // 2047
1245 
1246             MAX_SCALE-1,
1247             MAX_SCALE,
1248             MAX_SCALE+1,
1249             Integer.MAX_VALUE-1,
1250             Integer.MAX_VALUE
1251         };
1252 
1253         // Test cases where scaling is always a no-op
1254         for(int i=0; i < identityTestCases.length; i++) {
1255             for(int j=0; j < manyScalingFactors.length; j++) {
1256                 failures += testScalbCase(identityTestCases[i],
1257                                           manyScalingFactors[j],
1258                                           identityTestCases[i]);
1259             }
1260         }
1261 
1262         // Test cases where result is 0.0 or infinity due to magnitude
1263         // of the scaling factor
1264         for(int i=0; i < someTestCases.length; i++) {
1265             for(int j=0; j < manyScalingFactors.length; j++) {
1266                 int scaleFactor = manyScalingFactors[j];
1267                 if (Math.abs(scaleFactor) >= MAX_SCALE) {
1268                     double value = someTestCases[i];
1269                     failures+=testScalbCase(value,
1270                                             scaleFactor,
1271                                             FpUtils.copySign( (scaleFactor>0?infinityD:0.0), value) );
1272                 }
1273             }
1274         }
1275 
1276         // Test cases that could be done with one floating-point
1277         // multiply.
1278         for(int i=0; i < someTestCases.length; i++) {
1279             for(int j=0; j < oneMultiplyScalingFactors.length; j++) {
1280                 int scaleFactor = oneMultiplyScalingFactors[j];
1281                     double value = someTestCases[i];
1282 
1283                     failures+=testScalbCase(value,
1284                                             scaleFactor,
1285                                             value*powerOfTwoD(scaleFactor));
1286             }
1287         }
1288 
1289         // Create 2^MAX_EXPONENT
1290         double twoToTheMaxExp = 1.0; // 2^0
1291         for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++)
1292             twoToTheMaxExp *=2.0;
1293 
1294         // Scale-up subnormal values until they all overflow
1295         for(int i=0; i < subnormalTestCases.length; i++) {
1296             double scale = 1.0; // 2^j
1297             double value = subnormalTestCases[i];
1298 
1299             for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow
1300                 int scaleFactor = j;
1301 
1302                 failures+=testScalbCase(value,
1303                                         scaleFactor,
1304                                         (FpUtils.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ?
1305                                         FpUtils.copySign(infinityD, value) : // overflow
1306                                         // calculate right answer
1307                                         twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) );
1308                 scale*=2.0;
1309             }
1310         }
1311 
1312         // Scale down a large number until it underflows.  By scaling
1313         // down MAX_NORMALmm, the first subnormal result will be exact
1314         // but the next one will round -- all those results can be
1315         // checked by halving a separate value in the loop.  Actually,
1316         // we can keep halving and checking until the product is zero
1317         // since:
1318         //
1319         // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact
1320         // it will round *up*
1321         //
1322         // 2. When rounding first occurs in the expected product, it
1323         // too rounds up, to 2^-MAX_EXPONENT.
1324         //
1325         // Halving expected after rounding happends to give the same
1326         // result as the scalb operation.
1327         double expected = Double_MAX_VALUEmm *0.5f;
1328         for(int i = -1; i > -MAX_SCALE; i--) {
1329             failures+=testScalbCase(Double_MAX_VALUEmm, i, expected);
1330 
1331             expected *= 0.5;
1332         }
1333 
1334         // Tricky rounding tests:
1335         // Scale down a large number into subnormal range such that if
1336         // scalb is being implemented with multiple floating-point
1337         // multiplies, the value would round twice if the multiplies
1338         // were done in the wrong order.
1339 
1340         double value = 0x1.000000000000bP-1;
1341         expected     = 0x0.2000000000001P-1022;
1342         for(int i = 0; i < DoubleConsts.MAX_EXPONENT+2; i++) {
1343             failures+=testScalbCase(value,
1344                                     -1024-i,
1345                                     expected);
1346             value *=2.0;
1347         }
1348 
1349         return failures;
1350     }
1351 
1352     /* ************************* ulp tests ******************************* */
1353 
1354 
1355     /*
1356      * Test Math.ulp and StrictMath.ulp with +d and -d.
1357      */
1358     static int testUlpCase(float f, float expected) {
1359         float minus_f = -f;
1360         int failures=0;
1361 
1362         failures+=Tests.test("Math.ulp(float)", f,
1363                              Math.ulp(f), expected);
1364         failures+=Tests.test("Math.ulp(float)", minus_f,
1365                              Math.ulp(minus_f), expected);
1366         failures+=Tests.test("StrictMath.ulp(float)", f,
1367                              StrictMath.ulp(f), expected);
1368         failures+=Tests.test("StrictMath.ulp(float)", minus_f,
1369                              StrictMath.ulp(minus_f), expected);
1370         return failures;
1371     }
1372 
1373     static int testUlpCase(double d, double expected) {
1374         double minus_d = -d;
1375         int failures=0;
1376 
1377         failures+=Tests.test("Math.ulp(double)", d,
1378                              Math.ulp(d), expected);
1379         failures+=Tests.test("Math.ulp(double)", minus_d,
1380                              Math.ulp(minus_d), expected);
1381         failures+=Tests.test("StrictMath.ulp(double)", d,
1382                              StrictMath.ulp(d), expected);
1383         failures+=Tests.test("StrictMath.ulp(double)", minus_d,
1384                              StrictMath.ulp(minus_d), expected);
1385         return failures;
1386     }
1387 
1388     public static int testFloatUlp() {
1389         int failures = 0;
1390         float [] specialValues = {NaNf,
1391                                   Float.POSITIVE_INFINITY,
1392                                   +0.0f,
1393                                   +1.0f,
1394                                   +2.0f,
1395                                   +16.0f,
1396                                   +Float.MIN_VALUE,
1397                                   +Float_MAX_SUBNORMAL,
1398                                   +FloatConsts.MIN_NORMAL,
1399                                   +Float.MAX_VALUE
1400         };
1401 
1402         float [] specialResults = {NaNf,
1403                                    Float.POSITIVE_INFINITY,
1404                                    Float.MIN_VALUE,
1405                                    powerOfTwoF(-23),
1406                                    powerOfTwoF(-22),
1407                                    powerOfTwoF(-19),
1408                                    Float.MIN_VALUE,
1409                                    Float.MIN_VALUE,
1410                                    Float.MIN_VALUE,
1411                                    powerOfTwoF(104)
1412         };
1413 
1414         // Special value tests
1415         for(int i = 0; i < specialValues.length; i++) {
1416             failures += testUlpCase(specialValues[i], specialResults[i]);
1417         }
1418 
1419 
1420         // Normal exponent tests
1421         for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) {
1422             float expected;
1423 
1424             // Create power of two
1425             float po2 = powerOfTwoF(i);
1426             expected = FpUtils.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH-1));
1427 
1428             failures += testUlpCase(po2, expected);
1429 
1430             // Generate some random bit patterns for the significand
1431             for(int j = 0; j < 10; j++) {
1432                 int randSignif = rand.nextInt();
1433                 float randFloat;
1434 
1435                 randFloat = Float.intBitsToFloat( // Exponent
1436                                                  (Float.floatToIntBits(po2)&
1437                                                   (~FloatConsts.SIGNIF_BIT_MASK)) |
1438                                                  // Significand
1439                                                  (randSignif &
1440                                                   FloatConsts.SIGNIF_BIT_MASK) );
1441 
1442                 failures += testUlpCase(randFloat, expected);
1443             }
1444 
1445             if (i > FloatConsts.MIN_EXPONENT) {
1446                 float po2minus = FpUtils.nextAfter(po2,
1447                                                    Float.NEGATIVE_INFINITY);
1448                 failures += testUlpCase(po2minus, expected/2.0f);
1449             }
1450         }
1451 
1452         // Subnormal tests
1453 
1454         /*
1455          * Start with MIN_VALUE, left shift, test high value, low
1456          * values, and random in between.
1457          *
1458          * Use nextAfter to calculate, high value of previous binade,
1459          * loop count i will indicate how many random bits, if any are
1460          * needed.
1461          */
1462 
1463         float top=Float.MIN_VALUE;
1464         for( int i = 1;
1465             i < FloatConsts.SIGNIFICAND_WIDTH;
1466             i++, top *= 2.0f) {
1467 
1468             failures += testUlpCase(top, Float.MIN_VALUE);
1469 
1470             // Test largest value in next smaller binade
1471             if (i >= 3) {// (i == 1) would test 0.0;
1472                          // (i == 2) would just retest MIN_VALUE
1473                 testUlpCase(FpUtils.nextAfter(top, 0.0f),
1474                             Float.MIN_VALUE);
1475 
1476                 if( i >= 10) {
1477                     // create a bit mask with (i-1) 1's in the low order
1478                     // bits
1479                     int mask = ~((~0)<<(i-1));
1480                     float randFloat = Float.intBitsToFloat( // Exponent
1481                                                  Float.floatToIntBits(top) |
1482                                                  // Significand
1483                                                  (rand.nextInt() & mask ) ) ;
1484 
1485                     failures += testUlpCase(randFloat, Float.MIN_VALUE);
1486                 }
1487             }
1488         }
1489 
1490         return failures;
1491     }
1492 
1493     public static int testDoubleUlp() {
1494         int failures = 0;
1495         double [] specialValues = {NaNd,
1496                                   Double.POSITIVE_INFINITY,
1497                                   +0.0d,
1498                                   +1.0d,
1499                                   +2.0d,
1500                                   +16.0d,
1501                                   +Double.MIN_VALUE,
1502                                   +Double_MAX_SUBNORMAL,
1503                                   +DoubleConsts.MIN_NORMAL,
1504                                   +Double.MAX_VALUE
1505         };
1506 
1507         double [] specialResults = {NaNf,
1508                                    Double.POSITIVE_INFINITY,
1509                                    Double.MIN_VALUE,
1510                                    powerOfTwoD(-52),
1511                                    powerOfTwoD(-51),
1512                                    powerOfTwoD(-48),
1513                                    Double.MIN_VALUE,
1514                                    Double.MIN_VALUE,
1515                                    Double.MIN_VALUE,
1516                                    powerOfTwoD(971)
1517         };
1518 
1519         // Special value tests
1520         for(int i = 0; i < specialValues.length; i++) {
1521             failures += testUlpCase(specialValues[i], specialResults[i]);
1522         }
1523 
1524 
1525         // Normal exponent tests
1526         for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) {
1527             double expected;
1528 
1529             // Create power of two
1530             double po2 = powerOfTwoD(i);
1531             expected = FpUtils.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH-1));
1532 
1533             failures += testUlpCase(po2, expected);
1534 
1535             // Generate some random bit patterns for the significand
1536             for(int j = 0; j < 10; j++) {
1537                 long randSignif = rand.nextLong();
1538                 double randDouble;
1539 
1540                 randDouble = Double.longBitsToDouble( // Exponent
1541                                                  (Double.doubleToLongBits(po2)&
1542                                                   (~DoubleConsts.SIGNIF_BIT_MASK)) |
1543                                                  // Significand
1544                                                  (randSignif &
1545                                                   DoubleConsts.SIGNIF_BIT_MASK) );
1546 
1547                 failures += testUlpCase(randDouble, expected);
1548             }
1549 
1550             if (i > DoubleConsts.MIN_EXPONENT) {
1551                 double po2minus = FpUtils.nextAfter(po2,
1552                                                     Double.NEGATIVE_INFINITY);
1553                 failures += testUlpCase(po2minus, expected/2.0f);
1554             }
1555         }
1556 
1557         // Subnormal tests
1558 
1559         /*
1560          * Start with MIN_VALUE, left shift, test high value, low
1561          * values, and random in between.
1562          *
1563          * Use nextAfter to calculate, high value of previous binade,
1564          * loop count i will indicate how many random bits, if any are
1565          * needed.
1566          */
1567 
1568         double top=Double.MIN_VALUE;
1569         for( int i = 1;
1570             i < DoubleConsts.SIGNIFICAND_WIDTH;
1571             i++, top *= 2.0f) {
1572 
1573             failures += testUlpCase(top, Double.MIN_VALUE);
1574 
1575             // Test largest value in next smaller binade
1576             if (i >= 3) {// (i == 1) would test 0.0;
1577                          // (i == 2) would just retest MIN_VALUE
1578                 testUlpCase(FpUtils.nextAfter(top, 0.0f),
1579                             Double.MIN_VALUE);
1580 
1581                 if( i >= 10) {
1582                     // create a bit mask with (i-1) 1's in the low order
1583                     // bits
1584                     int mask = ~((~0)<<(i-1));
1585                     double randDouble = Double.longBitsToDouble( // Exponent
1586                                                  Double.doubleToLongBits(top) |
1587                                                  // Significand
1588                                                  (rand.nextLong() & mask ) ) ;
1589 
1590                     failures += testUlpCase(randDouble, Double.MIN_VALUE);
1591                 }
1592             }
1593         }
1594 
1595         return failures;
1596     }
1597 
1598     public static int testFloatSignum() {
1599         int failures = 0;
1600         float testCases [][] = {
1601             {NaNf,                      NaNf},
1602             {-infinityF,                -1.0f},
1603             {-Float.MAX_VALUE,          -1.0f},
1604             {-FloatConsts.MIN_NORMAL,   -1.0f},
1605             {-1.0f,                     -1.0f},
1606             {-2.0f,                     -1.0f},
1607             {-Float_MAX_SUBNORMAL,      -1.0f},
1608             {-Float.MIN_VALUE,          -1.0f},
1609             {-0.0f,                     -0.0f},
1610             {+0.0f,                     +0.0f},
1611             {Float.MIN_VALUE,            1.0f},
1612             {Float_MAX_SUBNORMALmm,      1.0f},
1613             {Float_MAX_SUBNORMAL,        1.0f},
1614             {FloatConsts.MIN_NORMAL,     1.0f},
1615             {1.0f,                       1.0f},
1616             {2.0f,                       1.0f},
1617             {Float_MAX_VALUEmm,          1.0f},
1618             {Float.MAX_VALUE,            1.0f},
1619             {infinityF,                  1.0f}
1620         };
1621 
1622         for(int i = 0; i < testCases.length; i++) {
1623             failures+=Tests.test("Math.signum(float)",
1624                                  testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);
1625             failures+=Tests.test("StrictMath.signum(float)",
1626                                  testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);
1627         }
1628 
1629         return failures;
1630     }
1631 
1632     public static int testDoubleSignum() {
1633         int failures = 0;
1634         double testCases [][] = {
1635             {NaNd,                      NaNd},
1636             {-infinityD,                -1.0},
1637             {-Double.MAX_VALUE,         -1.0},
1638             {-DoubleConsts.MIN_NORMAL,  -1.0},
1639             {-1.0,                      -1.0},
1640             {-2.0,                      -1.0},
1641             {-Double_MAX_SUBNORMAL,     -1.0},
1642             {-Double.MIN_VALUE,         -1.0d},
1643             {-0.0d,                     -0.0d},
1644             {+0.0d,                     +0.0d},
1645             {Double.MIN_VALUE,           1.0},
1646             {Double_MAX_SUBNORMALmm,     1.0},
1647             {Double_MAX_SUBNORMAL,       1.0},
1648             {DoubleConsts.MIN_NORMAL,    1.0},
1649             {1.0,                        1.0},
1650             {2.0,                        1.0},
1651             {Double_MAX_VALUEmm,         1.0},
1652             {Double.MAX_VALUE,           1.0},
1653             {infinityD,                  1.0}
1654         };
1655 
1656         for(int i = 0; i < testCases.length; i++) {
1657             failures+=Tests.test("Math.signum(double)",
1658                                  testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]);
1659             failures+=Tests.test("StrictMath.signum(double)",
1660                                  testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]);
1661         }
1662 
1663         return failures;
1664     }
1665 
1666 
1667     public static void main(String argv[]) {
1668         int failures = 0;
1669 
1670         failures += testFloatGetExponent();
1671         failures += testDoubleGetExponent();
1672 
1673         failures += testFloatNextAfter();
1674         failures += testDoubleNextAfter();
1675 
1676         failures += testFloatNextUp();
1677         failures += testDoubleNextUp();
1678 
1679         failures += testFloatNextDown();
1680         failures += testDoubleNextDown();
1681 
1682         failures += testFloatBooleanMethods();
1683         failures += testDoubleBooleanMethods();
1684 
1685         failures += testFloatCopySign();
1686         failures += testDoubleCopySign();
1687 
1688         failures += testFloatScalb();
1689         failures += testDoubleScalb();
1690 
1691         failures += testFloatUlp();
1692         failures += testDoubleUlp();
1693 
1694         failures += testFloatSignum();
1695         failures += testDoubleSignum();
1696 
1697         if (failures > 0) {
1698             System.err.println("Testing the recommended functions incurred "
1699                                + failures + " failures.");
1700             throw new RuntimeException();
1701         }
1702     }
1703 }